//
//  MyFileCacheBehavior.swift
//  RIBsTest
//
//  Created by lvzhao on 2024/5/25.
//

import Foundation


public enum MyDataCachePath: String {
    case cache = "/Library/Caches/"
    case document = "/Documents/"
    case tmp = "/tmp"
}


///FileCacheBehavior 只支持存储Data类型的数据, key 就是文件名, 若只存储简单的数据类型, 建议使用DefaultCacheBehavior


open class MyFileCacheBehavior: MyCacheBehavior {
    public func get<T>(key: String, isDecrypt: Bool) -> T? {
        
        if isDecrypt {
            return getDecryptData(key: key)
        } else {
            return getOriginalData(key: key)
        }
    }
    
    public func set<T>(key: String, data: T, isEncrypt: Bool) -> MyStoreErrorCode {
        if isEncrypt {
            return setEncryptData(key: key, data: data)
        } else {
            return setOriginalData(key: key, data: data)
        }
    }
}



public extension MyFileCacheBehavior {
    
    /// 获取文件路径
    /// - Parameters:
    ///   - fileName: 文件的名称
    ///   - path: 文件的的根目录
    /// - Returns: 完整的存储的路径
    func dataFilePath(fileName: String, path: MyDataCachePath) -> String {
        return NSHomeDirectory().appending(path.rawValue).appending(fileName)
    }
    
    func eraseFile(for key: String){
        guard let url = URL.init(string: self.dataFilePath(fileName: key, path: .document)) else { return }
        do {
            try FileManager.default.removeItem(atPath: url.path)
        } catch _{
            
        }
    }
    
    //读取源数据
    func getOriginalData<T>(key:String, path: MyDataCachePath = .document) -> T? {
        guard let url = URL.init(string: self.dataFilePath(fileName: key, path: path)) else { return nil }
        guard let data = FileManager.default.contents(atPath: url.path) else { return nil }
        guard let item = data as? T else { return nil }
        return item
    }
    
    //存储原数据
    func setOriginalData<T>(key:String, data: T, path: MyDataCachePath = .document) -> MyStoreErrorCode {
        guard let item = data as? Data else { return .typeError }
        let fileUrlPath = self.dataFilePath(fileName: key, path: path)
        if let url = URL.init(string: "file://\(fileUrlPath)") {
            do {
                try item.write(to: url)
                return .success
            } catch let error as NSError{
                return .setError
            }
        }
        return .setError
    }
    
    //读取解密后的数据
    func getDecryptData<T>(key: String, path: MyDataCachePath = .document) -> T? {
        guard let returnValue:Data = getOriginalData(key: key, path: path) else { return nil }
        guard let deValue = decrypt(key: key, data: returnValue) else { return nil }
        let deData = deValue.data(using: String.Encoding.utf8)
        guard let item = deData as? T else { return nil }
        return item
    }
    
    //存储加密有的数据
    func setEncryptData<T>(key: String, data: T, path: MyDataCachePath = .document) -> MyStoreErrorCode{
        guard let encode = encrypt(key: key, data: data) else { return .setError }
        let enData = encode.data(using: String.Encoding.utf8)
        return setOriginalData(key: key, data: enData, path: path)
    }
}

///加解密使用的方法
public extension MyFileCacheBehavior {
    func encrypt<T>(key: String?, data: T) -> String? {
        guard let item = data as? Data else {return nil}
        let newStr = String(data: item, encoding: String.Encoding.utf8)
        return MyCryptManager().encrypt(key: key, strToEncode: newStr, type: .aes)
    }
    
    func decrypt<T>(key: String?, data: T) -> String? {
        guard let item = data as? Data else {return nil}
        let newStr = String(data: item, encoding: String.Encoding.utf8)
        return MyCryptManager().decrypt(key: key, strToDecode: newStr, type: .aes)
    }
}
